package de.stefanocke.japkit.metaannotations;

import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;

import de.stefanocke.japkit.metaannotations.classselectors.None;

/**
 * Anntoation to add a field to a generated class.
 * @author stefan
 *
 */
public @interface Field {
	/**
	 * When the annotated annotation wants to override annotation values of the
	 * Method annotation, it must use this prefix.
	 * 
	 * @return
	 */
	String _prefix() default "<field>";
	
	/**
	 * By default, only one field is generated by that annotation. To generate multiple similar fields
	 * you can set an EL expression here. It must be an {@link Iterable} over {@link Element}. For each of those elements,
	 * a field is generated. The element is also used as rule source element for all matchers and EL expressions in the following.
	 * (For example, this allows for a nameExpr that determines the name depending on that element.)
	 * 
	 * @return
	 */
	String iterator() default "";
	
	/**
	 * 
	 * @return the language of the iterator expression. Defaults to Java EL.
	 */
	String iteratorLang() default "";
	
	/**
	 * EL Variables within the scope of the field. The root property "element"
	 * refers to the enclosing class or to the current element of the iterator.
	 * 
	 * @return
	 */
	Var[] vars() default {};
	
	/**
	 * By default, this method annotation is active and will generate a field.
	 * To switch it on or of case by case, a Matcher can be used here. 
	 * The element on which the matcher is applied is the enclosing class.
	 * 
	 * @return
	 */
	Matcher[] activation() default {};  
	
	/**
	 * 
	 * @return the name of the method. If not empty, nameExpr is ignored.
	 */
	String name() default "";
	
	/**
	 * For more complex cases: a Java EL expression to generate the name of the field. The root property "element" refers to the enclosing class.
	 * 
	 * @return 
	 */
	String nameExpr() default "";
	
	/**
	 * 
	 * @return the language of the name expression. Defaults to Java EL.
	 */
	String nameLang() default "";
	
	/**
	 * 
	 * @return the type of the field.
	 */
	Class<?> type() default None.class;
	
	Class<?>[] typeArgs() default {};
	
	/**
	 * 
	 * @return the modifiers of the field
	 */
	Modifier[] modifiers() default { };
	
	/**
	 * How to map annotations of the source element (???) to the field
	 * <p>
	 * 
	 * @return the annotation mappings
	 */
	AnnotationMapping[] annotationMappings() default {};
	
	
	/**
	 * Classes to be imported for the initializer. Allows to use short class names in the expr.
	 * The imports are only added if they don't conflict with others. Otherwise, it's an error.
	 * TODO: Instead of an error , we could replace the short name in the body by the fqn. 
	 * 
	 * @return
	 */
	Class<?>[] imports() default {};
			
	/**
	 * 
	 * @return a Java EL expression to generate the initializer. The root property "element" refers to the generated field.
	 */
	String initExpr() default "";
	
	/**
	 * 
	 * @return the language of the init expression. Default is Java EL.
	 */
	String initLang() default "";
	
	@interface List {
		Field[] value();
	}
}
